/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OHOS_HMFS_RESIZE_OPERATOR_H
#define OHOS_HMFS_RESIZE_OPERATOR_H

#include <iostream>
#include "hmfs_data.h"
#include "hmfs_utils.h"
#include "resize_command.h"
#include "resize_data.h"
#include "resize_utils.h"
#include "resize_defrag.h"

namespace OHOS {
namespace Hmfs {
class ResizeDefrag;
class ResizeOperator {
public:
    ResizeOperator(CmdConfig &resizeConfig);
    ~ResizeOperator() = default;
    void InitConfig();
    int32_t GetNewSuperBlock(struct SuperBlockData *sbData);
    int32_t ShrinkNats(struct SuperBlockData *newSbData);
    int32_t GetSumEntry(uint32_t blkAddr, struct SummaryEntry *sumEntry);
    struct SummaryBlockData* GetSumBlock(unsigned int segno, int *ret_type);
    int32_t MigrateMainArea(unsigned int offset);
    void MoveSsa(unsigned int segno, uint32_t newSumBlkAddr);
    void UpdateDataBlkaddr(uint32_t nid, uint16_t ofsInNode, uint32_t newAddr);
    void UpdateNatBlkaddr(uint32_t ino, uint32_t nid, uint32_t newaddr);
    int32_t MigrateSsa(struct SuperBlockData *newSbData, unsigned int offset);
    int32_t MigrateNat(struct SuperBlockData *newSbData);
    int32_t MigrateSit(struct SuperBlockData *newSbData, unsigned int offset);
    int32_t RebuildCheckpoint(struct SuperBlockData *newSbData, unsigned int offset);
    int32_t HmfsResizeCheck(struct SuperBlockData *newSbData);
    int32_t FlushNatJournalEntries();
    void RewriteCurrentSitPage(unsigned int segno, struct sitBlockData *sitBlk);
    int32_t FlushSitJournalEntries();
    void DuplicateCheckpoint();
    uint32_t GetFreeSegments();
    uint32_t UpdateNatBitsFlags(struct SuperBlockData *sbData, struct CheckPointData *cpData, uint32_t flags);
    uint32_t HmfsCheckpointChksum(struct CheckPointData *cpData);
    uint64_t GetCpCrc(struct CheckPointData *cpData);
    void WriteNatBits(struct SuperBlockData *sbData, struct CheckPointData *cpData, int set);
    int HmfsFsyncDevice();
    void WriteCheckpoint();
    void DupWriteCheckpoints();
    void FlushJournalEntries();
    void UpdateSuperBlock(struct SuperBlockData *superBlock, int sbMask);
    int32_t HmfsResizeExpand();
    int32_t HmfsResizeShrink();
    int32_t HmfsResize();
    int32_t CreateDeviceInfo();
    int32_t InitDeviceInfoToConfig();

private:
    CmdConfig &resizeConfig_; /** resize param */
    std::shared_ptr<HmfsConfigData> config_; /** config */
    std::shared_ptr<HmfsSbInfo> sbInfo_; /** sbi */
    std::unique_ptr<ResizeDefrag> reDefrag_;
};

// template<class T>
// class ResizeOperator : public Singleton<ResizeOperator<T>> {
// public:
//     T &GetResizeOperator();
// private:
//     T resizeOperator_;
// };

// template<class T>
// T &ResizeOperator<T>::GetResizeOperator()
// {
//     return resizeOperator_;
// }

}
}
#endif
